package com.gitee.melin.bee.core.fs.impl;

import com.gitee.melin.bee.core.fs.FileSystem;
import com.gitee.melin.bee.core.fs.FsConnectionInfo;
import io.minio.BucketExistsArgs;
import io.minio.MinioClient;
import io.minio.messages.Bucket;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MinioFileSystem implements FileSystem {
    private static final Logger LOGGER = LoggerFactory.getLogger(MinioFileSystem.class);

    @Override
    public boolean bucketExist(FsConnectionInfo connectionInfo) {
        try (MinioClient minioClient = MinioClient.builder()
                .endpoint(connectionInfo.getEndpoint())
                .credentials(connectionInfo.getAccessKeyId(), connectionInfo.getSecretAccessKey())
                .build()) {

            String bucket = connectionInfo.getBucket();
            BucketExistsArgs bucketExistsArgs =
                    BucketExistsArgs.builder().bucket(bucket).build();
            return minioClient.bucketExists(bucketExistsArgs);
        } catch (Exception e) {
            throw new RuntimeException("minio test connection error: " + e.getMessage(), e);
        }
    }

    public void testConnection(FsConnectionInfo connectionInfo) {
        boolean exists = bucketExist(connectionInfo);
        if (!exists) {
            throw new IllegalArgumentException("bucket not exist: " + connectionInfo.getBucket());
        }
    }

    @Override
    public List<String> queryBuckets(FsConnectionInfo connectionInfo) {
        try (MinioClient minioClient = MinioClient.builder()
                .endpoint(connectionInfo.getEndpoint())
                .credentials(connectionInfo.getAccessKeyId(), connectionInfo.getSecretAccessKey())
                .build()) {

            return this.queryBuckets(minioClient);
        } catch (Exception e) {
            throw new RuntimeException("test connection error: " + e.getMessage(), e);
        }
    }

    private List<String> queryBuckets(MinioClient minioClient) {
        try {
            return minioClient.listBuckets().stream().map(Bucket::name).collect(Collectors.toList());
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            throw new RuntimeException("query buckets error: " + e.getMessage(), e);
        }
    }
}
